package com.vehiclesecure.service;

import com.vehiclesecure.model.EmergencyAlert;
import com.vehiclesecure.model.User;
import com.vehiclesecure.repository.EmergencyAlertRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 紧急警报服务层，处理紧急警报的业务逻辑
 */
@Service
public class EmergencyAlertService {

    private final EmergencyAlertRepository emergencyAlertRepository;

    @Autowired
    public EmergencyAlertService(EmergencyAlertRepository emergencyAlertRepository) {
        this.emergencyAlertRepository = emergencyAlertRepository;
    }

    /**
     * 创建新的紧急警报
     * @param alert 警报对象
     * @return 创建后的警报
     */
    public EmergencyAlert createEmergencyAlert(EmergencyAlert alert) {
        // 设置默认值
        if (alert.getCreatedAt() == null) {
            alert.setCreatedAt(LocalDateTime.now());
        }
        if (alert.getStatus() == null) {
            alert.setStatus(EmergencyAlert.AlertStatus.ACTIVE);
        }
        if (alert.getCreatedBy() == null) {
            alert.setCreatedBy("SYSTEM");
        }
        
        // 根据alertType自动设置严重程度
        if (alert.getSeverity() == null && alert.getAlertType() != null) {
            alert.setSeverity(determineSeverityByAlertType(alert.getAlertType()));
        }
        
        // 生成设备签名（简化实现）
        alert.setDeviceSignature(generateDeviceSignature(alert.getVehicleId()));
        
        return emergencyAlertRepository.save(alert);
    }
    
    /**
     * 根据警报类型确定严重程度
     * @param alertType 警报类型
     * @return 严重程度
     */
    private EmergencyAlert.Severity determineSeverityByAlertType(String alertType) {
        // 将alertType转换为大写进行比较，避免大小写问题
        String type = alertType.toUpperCase();
        
        // 根据警报类型设置相应的严重程度
        switch (type) {
            case "THEFT_ATTEMPT":
            case "ENGINE_FAILURE":
            case "BRAKE_SYSTEM_FAILURE":
            case "AIRBAG_DEPLOYMENT":
            case "COLLISION_DETECTED":
                return EmergencyAlert.Severity.HIGH;
            case "ENGINE_OVERHEAT":
            case "BATTERY_LOW":
            case "TIRE_PRESSURE_CRITICAL":
            case "FUEL_EMPTY":
                return EmergencyAlert.Severity.MEDIUM;
            case "DOOR_OPEN":
            case "WINDOW_OPEN":
            case "LIGHTS_ON":
            case "TIRE_PRESSURE_LOW":
                return EmergencyAlert.Severity.LOW;
            default:
                // 默认中等严重程度
                return EmergencyAlert.Severity.MEDIUM;
        }
    }

    /**
     * 获取所有警报
     * @return 警报列表
     */
    public List<EmergencyAlert> getAllAlerts() {
        return emergencyAlertRepository.findAll();
    }
    
    /**
     * 获取当前用户有权访问的所有警报
     * @param user 当前登录用户
     * @return 用户有权访问的警报列表
     */
    public List<EmergencyAlert> getUserAccessibleAlerts(User user) {
        List<EmergencyAlert> alerts;
        
        // 服务商可以查看所有警报
        if (user != null && user.getRole().equals(User.Role.SERVICE_PROVIDER)) {
            alerts = emergencyAlertRepository.findAll();
        }
        
        else if (user == null || user.getVehicleIds() == null || user.getVehicleIds().isEmpty()) {
            return List.of();
        }
        
        // 对于普通用户，只返回其有权访问的车辆的警报
        else if (!user.getRole().equals(User.Role.ADMIN)) {
            // 分别查询每辆车的警报并合并
            alerts = user.getVehicleIds().stream()
                    .flatMap(vehicleId -> emergencyAlertRepository.findByVehicleId(vehicleId).stream())
                    .sorted((a1, a2) -> a2.getCreatedAt().compareTo(a1.getCreatedAt())) // 按时间倒序
                    .collect(Collectors.toList());
        }
        
        // 管理员可以查看所有警报
        else {
            alerts = emergencyAlertRepository.findAll();
        }
        
        // 为没有severity字段的警报设置严重程度
        return alerts.stream()
                .peek(alert -> {
                    if (alert.getSeverity() == null && alert.getAlertType() != null) {
                        alert.setSeverity(determineSeverityByAlertType(alert.getAlertType()));
                    }
                })
                .collect(Collectors.toList());
    }
    
    /**
     * 检查用户是否有权访问指定车辆的警报
     * @param user 当前登录用户
     * @param vehicleId 车辆ID
     * @return 是否有权访问
     */
    public boolean hasAccessToVehicleAlerts(User user, String vehicleId) {
        // 管理员和服务商可以访问所有车辆的警报
        if (user != null && (user.getRole().equals(User.Role.ADMIN) || user.getRole().equals(User.Role.SERVICE_PROVIDER))) {
            return true;
        }
        
        // 普通用户只能访问其vehicleIds列表中的车辆的警报
        return user != null && user.getVehicleIds() != null && user.getVehicleIds().contains(vehicleId);
    }
    
    /**
     * 获取当前用户有权访问的活动警报
     * @param user 当前登录用户
     * @return 用户有权访问的活动警报列表
     */
    public List<EmergencyAlert> getUserAccessibleActiveAlerts(User user) {
        // 服务商可以查看所有活动警报
        if (user != null && user.getRole().equals(User.Role.SERVICE_PROVIDER)) {
            return emergencyAlertRepository.findByStatus(EmergencyAlert.AlertStatus.ACTIVE);
        }
        
        if (user == null || user.getVehicleIds() == null || user.getVehicleIds().isEmpty()) {
            return List.of();
        }
        
        // 对于普通用户，只返回其有权访问的车辆的活动警报
        if (!user.getRole().equals(User.Role.ADMIN)) {
            // 分别查询每辆车的活动警报并合并
            return user.getVehicleIds().stream()
                    .flatMap(vehicleId -> {
                        List<EmergencyAlert> alerts = emergencyAlertRepository.findByVehicleId(vehicleId);
                        return alerts.stream()
                                .filter(alert -> alert.getStatus() == EmergencyAlert.AlertStatus.ACTIVE);
                    })
                    .sorted((a1, a2) -> a2.getCreatedAt().compareTo(a1.getCreatedAt())) // 按时间倒序
                    .collect(Collectors.toList());
        }
        
        // 管理员可以查看所有活动警报
        return emergencyAlertRepository.findByStatus(EmergencyAlert.AlertStatus.ACTIVE);
    }

    /**
     * 根据车辆ID获取警报
     * @param vehicleId 车辆唯一标识符
     * @return 警报列表
     */
    public List<EmergencyAlert> getAlertsByVehicleId(String vehicleId) {
        return emergencyAlertRepository.findByVehicleId(vehicleId);
    }

    /**
     * 根据状态获取警报
     * @param status 警报状态
     * @return 警报列表
     */
    public List<EmergencyAlert> getAlertsByStatus(EmergencyAlert.AlertStatus status) {
        return emergencyAlertRepository.findByStatus(status);
    }

    /**
     * 获取所有活动的警报
     * @return 活动警报列表
     */
    public List<EmergencyAlert> getActiveAlerts() {
        return emergencyAlertRepository.findByStatus(EmergencyAlert.AlertStatus.ACTIVE);
    }

    /**
     * 根据ID获取警报
     * @param id 警报ID
     * @return 警报对象
     */
    public Optional<EmergencyAlert> getAlertById(String id) {
        return emergencyAlertRepository.findById(id);
    }

    /**
     * 解决警报
     * @param id 警报ID
     * @param resolvedBy 解决者
     * @return 解决后的警报
     */
    public EmergencyAlert resolveAlert(String id, String resolvedBy) {
        EmergencyAlert alert = emergencyAlertRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("警报不存在"));
        
        alert.setStatus(EmergencyAlert.AlertStatus.RESOLVED);
        alert.setResolvedAt(LocalDateTime.now());
        alert.setResolvedBy(resolvedBy);
        
        return emergencyAlertRepository.save(alert);
    }

    /**
     * 标记警报为无效
     * @param id 警报ID
     * @return 标记后的警报
     */
    public EmergencyAlert markAlertAsInvalid(String id) {
        EmergencyAlert alert = emergencyAlertRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("警报不存在"));
        
        alert.setStatus(EmergencyAlert.AlertStatus.INVALID);
        
        return emergencyAlertRepository.save(alert);
    }

    /**
     * 获取时间范围内的警报
     * @param start 开始时间
     * @param end 结束时间
     * @return 警报列表
     */
    public List<EmergencyAlert> getAlertsInTimeRange(LocalDateTime start, LocalDateTime end) {
        return emergencyAlertRepository.findByCreatedAtBetween(start, end);
    }

    /**
     * 生成设备签名
     * @param vehicleId 车辆唯一标识符
     * @return 设备签名字符串
     */
    private String generateDeviceSignature(String vehicleId) {
        // 实际应用中应该使用更安全的签名算法
        return UUID.nameUUIDFromBytes((vehicleId + LocalDateTime.now().toString()).getBytes()).toString();
    }
}